#ifndef _SESSION_H_
#define _SESSION_H_

#include <iostream>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/thread.hpp>
#include "DllManager.h"
#include "../../../../Common/PackageUtil.h"

using boost::asio::ip::tcp;
using namespace std;

#define _DEBUG_LEVEL_1_

class Logic
{
public:
	enum ErrorNo
	{
		ErrHeadError = 1,
		ErrDllLoadError = 2,
		ErrDataProcessError = 3,
	};

	long delay_ms;
	int drop_info_len;
	
private:

	DllManager _dll_manager;
	vector<char *> _package_head_list;
	vector<int> _package_len_list;

public:
	Logic();
	~Logic();

	void Init();

	int ProcessData(int thread_id, char *buf, int len);
	void GetDelayBuf(long & delay_ms, char * * p_buf, int & len);
	enum Common::DataType ProcessDownStreamPackage(int index, char *&p_data, int &len);

private:
	int ParseHead(char *buf, int len = 0);
	int SendDataToGameServer(char *buf, int len);
	int RecvDataFromGameServer(char *buf, int &len);
	void ProcessDelayData(char * buf, int &len);
	void FillErrorData(ErrorNo error_no, char *buf, int &len);
	int GetPackageNum(char *buf, int len);
	void RegroupPackage();
	void SetPackageMultiDataFlag(char *buf, int len);
};

class Session : public boost::enable_shared_from_this<Session>
{	
private:
	tcp::socket _socket;
	char _package[MAX_PACKAGE_SIZE];
	int _package_len;

	Logic _logic;
	boost::asio::io_service &_io_service;
	
	int _is_control;

public:
	int thread_id;

public:
	Session(boost::asio::io_service &io_service);
	~Session();

	tcp::socket & Socket();
	void Start();
	void StartControl();

	void CallbackDelaySend(const boost::system::error_code& ec, char *buf, int len,
		boost::asio::deadline_timer *p_timer);
	void CallbackDelayProcess(const boost::system::error_code& ec, char *buf,
		int len, boost::asio::deadline_timer *p_timer);
	

private:
	void HandleWrite(const boost::system::error_code &error);
	void HandleRead(const boost::system::error_code &error, size_t bytes_transferred);
	
	void HandleReadControl(const boost::system::error_code &error, size_t bytes_transferred);

	void ProcessUpData(char *buf, int len);
	void StartDelay(long delay_ms, char *buf, int len, Common::DataType data_type);

	void DeleteSelf();
};

#endif
